package main

import (
	"embed"
	"fmt"
	"github.com/joho/godotenv"
	"io"
	"io/fs"
	"log"
	"monoblog/common/register"
	"monoblog/config"
	_ "monoblog/domain/service/impl"
	"monoblog/domain/service/listener"
	"monoblog/domain/service/schedule"
	"monoblog/middleware"
	"monoblog/router"
	"net/http"
	"os"
	"path"
	"runtime"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

func init() {
	fmt.Println("init ...")

	// 加载项目根目录的 .env 文件
	err := godotenv.Load()
	if err != nil {
		log.Fatalf("加载 .env 文件失败: %v", err)
	}

	gin.SetMode(gin.ReleaseMode)

	InitAllConfig() //初始化所有配置

	register.Refresh() //如果不刷新，则延迟到使用时在创建
}

//go:embed templates/** static/** favicon.ico
var embeddedFiles embed.FS

//PowerShell：打包命令： $env:GOOS = "windows"; $env:GOARCH = "amd64"; go build -o build/monoblog.exe main.go

func main() {
	r := gin.Default()

	// 允许Gin信任本地代理服务器（Nginx），解析 X-Forwarded-For 等头获取真实 IP
	if err := r.SetTrustedProxies([]string{"127.0.0.1"}); err != nil {
		log.Fatalf("Gin设置信任代理失败: %v", err)
	}

	// 使用标准的LoadHTMLGlob用于开发，生产模式下使用嵌入的模板
	if gin.Mode() == gin.DebugMode {
		r.LoadHTMLGlob("templates/**")
		r.Static("/static", "./static")
		r.StaticFile("/favicon.ico", "./favicon.ico")
	} else {
		templatesSub, _ := fs.Sub(embeddedFiles, "templates")
		r.LoadHTMLFS(http.FS(templatesSub), "*.tmpl")

		staticFS, _ := fs.Sub(embeddedFiles, "static")
		r.StaticFS("/static", http.FS(staticFS))

		faviconFS, _ := fs.Sub(embeddedFiles, ".") // 根路径下的favicon.ico
		r.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(faviconFS))
	}

	//全局的中间件
	r.Use(middleware.MaxBytesLimit(100 * middleware.MB))

	router.ViewRoute(&r.RouterGroup)   //页面路由
	router.Route(&r.RouterGroup)       //API路由
	schedule.RegisterAndRunSchedules() //初始化定时任务
	listener.RunListeners()            //启动通知监听器

	//启动服务
	err := r.Run(":8082")

	if err != nil {
		panic(fmt.Sprintf("启动服务器失败: %v", err.Error()))
		return
	}
}

func InitAllConfig() {
	logrus.Infof("启动环境 env GIN_MODE = %s ...", gin.Mode())

	InitLogs(gin.Mode() == gin.DebugMode) //设置日志打印

	var redisProperties = &config.RedisProperties{
		Addr:     os.Getenv("REDIS_ADDR"),
		Password: os.Getenv("REDIS_PASSWORD"),
		DB:       2,
	}
	config.InitRedis(redisProperties)

	var dbProperties = &config.DatabaseProperties{
		DbName:   "monoblog",
		Host:     os.Getenv("MONGODB_HOST"),
		Username: os.Getenv("MONGODB_USERNAME"),
		Password: os.Getenv("MONGODB_PASSWORD"),
	}
	config.InitMongoDB(dbProperties)

	var minioProperties = &config.MinioProperties{
		Endpoint:        os.Getenv("MINIO_Endpoint"),
		AccessKeyID:     os.Getenv("MINIO_ACCESS_KEY"),
		SecretAccessKey: os.Getenv("MINIO_SECRET_KEY"),
		Bucket:          "blog-picture",
	}
	config.InitMinioClient(minioProperties)

	config.InitManticoreSQL(&config.ManticoreProperties{
		Endpoint: os.Getenv("MANTICORE_Endpoint"),
	})
}

// InitLogs 初始化日志配置
func InitLogs(debug bool) {
	if !debug {
		gin.DefaultWriter = io.Discard // 禁止 Gin 的日志打印
	}

	//日志格式
	logrus.SetFormatter(&logrus.TextFormatter{
		ForceColors:     true,                  //显示颜色
		FullTimestamp:   true,                  // 完整时间
		TimestampFormat: "2006-01-02 15:04:05", // 时间格式
		CallerPrettyfier: func(f *runtime.Frame) (string, string) {
			filename := path.Base(f.File)
			//自定义你想要的格式
			return "", fmt.Sprintf("%28s:%d ->", filename, f.Line)
		},
	})
	logrus.SetReportCaller(true) // 显示行号
	if debug {
		logrus.SetLevel(logrus.DebugLevel)
	} else {
		logrus.SetLevel(logrus.InfoLevel)
	}

}
